﻿using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PlatformerCS
{
    class Player : Entity
    {
        // System
        FrameCounter fpsCounter;
        GameBoard game;

        // Graphics
        PlayerAnimation animationMgr;
        Camera2D camera;
        Texture2D aim;
        SpriteFont font;

        // Inputs
        KeyboardState Kstate, prevKstate;
        MouseState mouse;

        // Movement
        int orientation;
        float speed = 5f;

        // Gameplay
        Vector2 spawnPosition = new Vector2(100, 100);
        Boolean alive;
        Gun gun;

        /// <summary>
        /// Orientation of the player.
        /// 1  : looking to the right
        /// -1 : looking to the left
        /// </summary>
        public int Orientation
        {
            get { return orientation; }
        }

        public Player(GameBoard game)
        {
            this.game = game;
            Initialize(game.Content);
            Spawn();
        }

        /// <summary>
        /// Update the player.
        /// </summary>
        public void Update()
        {
            if (!alive)
                return;
            HandleMovement();
            HandleShoot();
            gun.Update();
            HandleAnimation();
        }

        /// <summary>
        /// Render the player on the game world.
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawWorld(SpriteBatch spriteBatch)
        {
            animationMgr.Draw(spriteBatch);
            gun.DrawWorld(spriteBatch);
        }

        /// <summary>
        /// Display some data on screen.
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void DrawStats(SpriteBatch spriteBatch, GameTime gameTime)
        {
            gun.DrawStats(spriteBatch);
            fpsCounter.Draw(spriteBatch, gameTime);
            spriteBatch.Draw(aim, new Vector2(mouse.X, mouse.Y), Color.White);
            spriteBatch.DrawString(font, "Bullets : " + gun.Bullets.Count, new Vector2(GameBoard.WIDTH - 200, 20), Color.Black);
            spriteBatch.DrawString(font, "Position : (" + position.X + "," + position.Y + ")", new Vector2(GameBoard.WIDTH - 200, 40), Color.Black);
        }

        /// <summary>
        /// Spawn the player in his base.
        /// </summary>
        public void Spawn()
        {
            alive = true;
            position = spawnPosition;
        }

        public override void DealDamage(int dmg)
        {

        }


        // Initialize the graphic components
        // Must be called only once during runtime
        private void Initialize(ContentManager content)
        {
            // SpriteSheet
            Animation.AnimInfo anim = new Animation.AnimInfo();
            anim.Current = new Rectangle(0, 0, 64, 80);
            anim.MaxSize = new Point(9, 1);
            anim.Rate = 5;
            anim.Texture = content.Load<Texture2D>("Player/sprite-sheet");
            animationMgr = new PlayerAnimation(this, anim);

            // Object instances
            camera = new Camera2D();
            fpsCounter = new FrameCounter();

            // Fonts & texture
            font = content.Load<SpriteFont>("Fonts/Menu");
            LoadTexture(content, "Player/sprite-sheet");
            fpsCounter.LoadContent(content);
            gun = new Gun(content);
            aim = content.Load<Texture2D>("Player/aim");
        }

        // Handle player spritesheet
        private void HandleAnimation()
        {
            animationMgr.Update();

            if (orientation == 1)
                animationMgr.SetAnimation(0);
            else
                animationMgr.SetAnimation(0);
        }

        // Handle the player movements
        private void HandleMovement()
        {
            prevKstate = Kstate;
            Kstate = Keyboard.GetState();

            if (Kstate.IsKeyDown(Keys.Z))
                position.Y -= speed;
            else if (Kstate.IsKeyDown(Keys.S))
                position.Y += speed;

            if (Kstate.IsKeyDown(Keys.D))
                position.X += speed;
            else if (Kstate.IsKeyDown(Keys.Q))
                position.X -= speed;

            camera.Update(position, new Point(animationMgr.Width, animationMgr.Height));
        }

        // Handle the aim and the shooting
        private void HandleShoot()
        {
            mouse = Mouse.GetState();
            if (mouse.X < GameBoard.WIDTH / 2)
                orientation = -1;
            else
                orientation = 1;

            if (mouse.LeftButton == ButtonState.Pressed)
            {
                Weapon.BulletAddInfo info = new Weapon.BulletAddInfo();
                info.Orientation = orientation;
                info.Start = position;// +new Vector2(GameBoard.WIDTH / 2 + 50, GameBoard.HEIGHT / 2 - 100);
                info.End = new Vector2(mouse.X + aim.Width / 2 - 10, mouse.Y + aim.Height / 2 - 10);
                info.Content = game.Content;

                gun.ShootBullet(info);
            }
        }

        /* Properties */
        public Camera2D Camera
        {
            get { return camera; }
        }
    }
}
